package dolf.objects;

import java.awt.Graphics2D;
import java.util.List;

import dolf.game.*;
import dolf.objects.weapons.Weapon;
import dolf.objects.WorldObject;

public class Bullet extends CircleObject implements java.io.Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int timer = 10; 
	private Player pl;
	private int damage;
	private boolean heavy = false;
	private boolean inBall = false;
	private Ball lastHitted = null;
	private double recoil = 0;
	public Bullet(Point pos, Vector motion, Player _pl, int _damage){
		super(pos,1,true,true);
		this.setCollitabe(false);
		this.setMotion(motion);
		this.damage = _damage;
		this.pl = _pl;
	}
	public Bullet(Point pos, Vector motion, Player _pl, int _damage, boolean _heavy, double _recoil){
		super(pos,1,true,true);
		this.setCollitabe(false);
		this.setMotion(motion);
		this.damage = _damage;
		this.pl = _pl;
		this.heavy = _heavy;
		this.recoil = _recoil;
	}
	public void move(List<WorldObject> objects, double usedMotion, WorldObject lastKoll){
		if(this.getPosition().getX()>Level.getInstance().getWidth() || this.getPosition().getX() < 0
				|| this.getPosition().getY()>Level.getInstance().getHeight() || this.getPosition().getY() < 0){
			Level.getInstance().removeObject(this);
		}
		double rest = 0;
		if(this.timer > 0){
			this.timer--;
		}
		WorldObject koll = null;
		/* Wenn Bewegung zu gering => keine Bewegung*/
		/* Kollisions abfrage*/
		double tmprest; 
		rest = this.getRadius()+this.getMotion().getLength()+1; // sicher groesser als jeder Kollisionswert
		for(WorldObject obj:objects){
			if(obj.isVisible() && obj.isCollitabe() && obj != this && !(obj instanceof Weapon) && !(obj.isFlat())){
				if((tmprest = this.kollision(obj))>=0){
					if(!(tmprest == rest) || obj instanceof CircleObject){
						if(tmprest < rest ){
							rest = tmprest;
							koll = obj;
						}
					} 
				}
			}	
		}

		if(koll==null){
			/* bewegung ohne kollision*/
			this.moveNormal();
			return;
		} else{
			/*bewgenung mit kollision*/
			this.newMotion(koll);
			return;
		} 
	}
	public void paint(Graphics2D g){
		if(this.inBall){
			this.inBall = false;
		} else {
			g.drawOval(this.getPosition().getIntX(), this.getPosition().getIntY(), this.getRadius(), this.getRadius());
		}
	}
	public boolean newMotion(WorldObject object){
		boolean ret = false;
		boolean ball;
		if((ball=(object instanceof Ball)) && object != lastHitted){
			Ball obj = (Ball) object;
			this.lastHitted = obj;
			if(obj.getPlayer() == this.pl && this.timer > 0){
				return true;
			}
			if(obj.getPlayer().getHP()>this.damage){
				ret = true;
			}
			obj.getPlayer().setHP(obj.getPlayer().getHP()-this.damage);
			pl.addDamage(this.damage);
			if(this.recoil != 0){
				obj.setMotion(obj.getMotion().add(this.getMotion().setLength(this.recoil)));
				this.recoil *= 0.75;
			}
			if(this.heavy){
				this.damage--;
			}
			
			//obj.getMotion().add(this.getMotion().setLength(0.1));
		}
		if((object.isFlat() || (ball=(this.heavy && ball))) && this.damage>0){
			this.moveNormal();
			if(ball && !object.isFlat()){
				this.inBall = true;
			}
			return true;
		}
		Level.getInstance().removeObject(this);
		return ret;
	}
	private void moveNormal(){
		this.setPosition(new Point(this.getPosition().getX()+this.getMotion().getX(),this.getPosition().getY()+this.getMotion().getY()));
	}
}
